/*
 * 文件名： ApaySpdbBankServiceImpl.java
 * 
 * 工程名称: bis-bank-spdb
 *
 * Gopay
 *
 * 创建日期： 2017年11月9日
 *
 * Copyright(C) 2017, by www.gopay.com.cn Inc.All rights reserved.
 *
 * 原始作者: 宣广海
 *
 */
package com.gopay.bis.spdb.appay.impl;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.bis.spdb.appay.operation.ApaySpdbCerHelper;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.spdb.agpay.MicroPayBody;
import com.gopay.common.domain.bank.spdb.agpay.QueryOrderBody;
import com.gopay.common.domain.bank.spdb.agpay.RefundBody;
import com.gopay.common.domain.bank.spdb.agpay.ReverseBody;
import com.gopay.common.domain.bank.spdb.agpay.ScanPayBody;
import com.gopay.common.domain.bank.spdb.agpay.SdkPayBody;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.HttpTransport;
import com.gopay.remote.bank.businesses.MicroPayService;
import com.gopay.remote.bank.businesses.ScanPayService;

/**
 * 
 *
 * @author 宣广海
 *
 * @version 
 *
 * @since 2017年11月9日
 */
public class ApaySpdbBankServiceImpl implements ScanPayService,MicroPayService{

	private static Logger logger = LoggerFactory.getLogger(ApaySpdbBankServiceImpl.class);
	
	private ApaySpdbCerHelper apaySpdbCerHelper; 
	
	private HttpTransport aPayHttpTransport;
	
	@Override
	public Object verify(BaseMessage baseMsg) throws GopayException {
		// TODO Auto-generated method stub
		return (boolean)apaySpdbCerHelper.verify(baseMsg);
	}

	@Override
	public Object payment(BaseMessage baseMsg) throws GopayException {
		// TODO Auto-generated method stub
		if(baseMsg instanceof SdkPayBody){
			SdkPayBody req = (SdkPayBody) baseMsg;
			req.setSign(apaySpdbCerHelper.sign(req));
			SdkPayBody resData = send(baseMsg, req, SdkPayBody.class);
			if(null!=resData){
				if("03".equals(resData.getRespcd())){
					return resData;
				}
			}
			resData.setSignKey(req.getSignKey());
			if((boolean)apaySpdbCerHelper.verify(resData)){
				return resData;
			}
		}else if(baseMsg instanceof ScanPayBody){
			ScanPayBody req = (ScanPayBody) baseMsg;
			req.setSign(apaySpdbCerHelper.sign(req));
			ScanPayBody resData = send(baseMsg, req, ScanPayBody.class);
			if(null!=resData){
				if("03".equals(resData.getRespcd())){
					return resData;
				}
			}
			resData.setSignKey(req.getSignKey());
			if((boolean)apaySpdbCerHelper.verify(resData)){
				return resData;
			}
		}else if(baseMsg instanceof MicroPayBody){
			MicroPayBody req = (MicroPayBody) baseMsg;
			req.setSign(apaySpdbCerHelper.sign(req));
			MicroPayBody resData = send(baseMsg, req, MicroPayBody.class);
			if(null!=resData){
				if("03".equals(resData.getRespcd())){
					return resData;
				}
			}
			resData.setSignKey(req.getSignKey());
			if((boolean)apaySpdbCerHelper.verify(resData)){
				resData.setSuccess(true);
				return resData;
			}
		}
		return null;
	}
	
	private <T> T send(BaseMessage baseMsg, Object body, Class<T> clazz) throws GopayException{
		try {
			String data = apaySpdbCerHelper.getJson(body, clazz);
			aPayHttpTransport.setUrl(baseMsg.getPayUrl());
			String res = aPayHttpTransport.submit(data.getBytes("UTF-8"));
			logger.error("spdb agpay payment return msg = " + res);
			if(StringUtils.isNotBlank(res)){
				return apaySpdbCerHelper.fromJson(res, clazz);
			}
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E7026);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.error("send occur error ", e.getMessage());
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E7026);
		}
	}
	
	@Override
	public Object refund(BaseMessage baseMsg) throws GopayException {
		RefundBody req = (RefundBody) baseMsg;
		req.setSign(apaySpdbCerHelper.sign(req));
		RefundBody resData = send(baseMsg, req, RefundBody.class);
		if(null!=resData){
			if("03".equals(resData.getRespcd())){
				return resData;
			}
		}
		resData.setSignKey(req.getSignKey());
		if((boolean)apaySpdbCerHelper.verify(resData)){
			return resData;
		}
		return null;
	}

	@Override
	public Object queryOrder(BaseMessage baseMsg) throws GopayException {
		QueryOrderBody req = (QueryOrderBody) baseMsg;
		req.setSign(apaySpdbCerHelper.sign(req));
		QueryOrderBody resData = send(baseMsg, req, QueryOrderBody.class);
		if(null!=resData){
			if("03".equals(resData.getRespcd())){
				return resData;
			}
		}
		resData.setSignKey(req.getSignKey());
		if((boolean)apaySpdbCerHelper.verify(resData)){
			return resData;
		}
		return null;
	}

	@Override
	public Object refundQuery(Object msg) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

	public void setApaySpdbCerHelper(ApaySpdbCerHelper apaySpdbCerHelper) {
		this.apaySpdbCerHelper = apaySpdbCerHelper;
	}

	public void setaPayHttpTransport(HttpTransport aPayHttpTransport) {
		this.aPayHttpTransport = aPayHttpTransport;
	}

	@Override
	public Object refundQuery(BaseMessage msg) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object reverse(BaseMessage baseMsg) throws GopayException {
		ReverseBody req = (ReverseBody) baseMsg;
		req.setSign(apaySpdbCerHelper.sign(req));
		ReverseBody resData = send(baseMsg, req, ReverseBody.class);
		if(null!=resData){
			if("03".equals(resData.getRespcd())){
				return resData;
			}
		}
		resData.setSignKey(req.getSignKey());
		
		if((boolean)apaySpdbCerHelper.verify(resData)){
			logger.info("验签成功");
			resData.setSuccess(true);
			return resData;
		}
		return null;
	}
}
